﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.DirectoryServices.AccountManagement;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.ServiceModel.Description;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Discovery;

namespace Config
{
  public partial class Form1 : Form
  {
    private readonly QueueManager.Helper.Crm.CustomCrmServiceHelper _serverConnect = new QueueManager.Helper.Crm.CustomCrmServiceHelper();
    private string _Config = string.Empty;
    private Configuration _mpsConfig;

    public Form1()
    {
      InitializeComponent();

      var m = new ExeConfigurationFileMap();
      m.ExeConfigFilename = "QueueManager.Service.exe.config";
      _mpsConfig = ConfigurationManager.OpenMappedExeConfiguration(m, ConfigurationUserLevel.None);

    }

    private void btLocate_Click(object sender, EventArgs e)
    {
      try
      {
        btLocate.Text = "Verifying...";
        plConnection.Enabled = false;
        _serverConnect.SetServerConfiguration(tbServerAddress.Text, cbSSL.Checked, cbO365Org.Checked);
        switch (_serverConnect.config.EndpointType)
        {
          case AuthenticationProviderType.None:
            break;
          case AuthenticationProviderType.ActiveDirectory:
            lbUsername.Text = "Username [domain\\username]:";
            break;
          case AuthenticationProviderType.Federation:
            lbUsername.Text = "Enter Username: ";
            break;
          case AuthenticationProviderType.LiveId:
            lbUsername.Text = "Enter Live ID: ";
            break;
          case AuthenticationProviderType.OnlineFederation:
            lbUsername.Text = "Enter Username: ";
            break;
          default:
            throw new ArgumentOutOfRangeException();
        }

        //Show user and password
        plAuthentication.Enabled = true;
        btLocate.Text = "Success";
      }
      catch (Exception ex)
      {
        btLocate.Text = "Verify connection";
        plConnection.Enabled = true;
        MessageBox.Show(ex.Message, "An error has occured!", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }

    }

    private void btConnect_Click(object sender, EventArgs e)
    {
      try
      {
        plAuthentication.Enabled = false;
        btConnect.Text = "Connecting...";
        _serverConnect.SetUserLogonCredentials(tbUsername.Text, tbPassword.Text);
        ddOrganization.DisplayMember = "FriendlyName";
        ddOrganization.ValueMember = "UrlName";

        var organizations = _serverConnect.GetOrganizations();
        ddOrganization.DataSource = organizations;
        plOrganization.Enabled = true;
        btConnect.Text = "Success";
      }
      catch (Exception ex)
      {
        btConnect.Text = "Connect to server";
        plAuthentication.Enabled = true;
        var message = ex.InnerException == null ? ex.Message : ex.InnerException.Message;
        MessageBox.Show(message, "An error has occured!", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }

    }

    private void btSave_Click(object sender, EventArgs e)
    {
      _serverConnect.config.OrganizationName = ((OrganizationDetail)ddOrganization.SelectedItem).FriendlyName;
      _serverConnect.config.OrganizationUri = new System.Uri(((OrganizationDetail)ddOrganization.SelectedItem).Endpoints[EndpointType.OrganizationService]);

      _mpsConfig.AppSettings.Settings.Remove("ServerAddress");
      _mpsConfig.AppSettings.Settings.Add("ServerAddress", _serverConnect.config.ServerAddress);
      _mpsConfig.AppSettings.Settings.Remove("OrganizationName");
      _mpsConfig.AppSettings.Settings.Add("OrganizationName", _serverConnect.config.OrganizationName);
      _mpsConfig.AppSettings.Settings.Remove("DiscoveryUri");
      _mpsConfig.AppSettings.Settings.Add("DiscoveryUri", _serverConnect.config.DiscoveryUri != null ? _serverConnect.config.DiscoveryUri.OriginalString : String.Empty);
      _mpsConfig.AppSettings.Settings.Remove("OrganizationUri");
      _mpsConfig.AppSettings.Settings.Add("OrganizationUri", _serverConnect.config.OrganizationUri != null ? _serverConnect.config.OrganizationUri.OriginalString : String.Empty);
      _mpsConfig.AppSettings.Settings.Remove("HomeRealmUri");
      _mpsConfig.AppSettings.Settings.Add("HomeRealmUri", _serverConnect.config.HomeRealmUri != null ? _serverConnect.config.HomeRealmUri.OriginalString : String.Empty);

      switch (_serverConnect.config.EndpointType)
      {
        case AuthenticationProviderType.ActiveDirectory:
          _mpsConfig.AppSettings.Settings.Remove("UserName");
          _mpsConfig.AppSettings.Settings.Add("UserName", _serverConnect.config.Credentials.Windows.ClientCredential.UserName);
          _mpsConfig.AppSettings.Settings.Remove("Domain");
          _mpsConfig.AppSettings.Settings.Add("Domain", _serverConnect.config.Credentials.Windows.ClientCredential.Domain);
          break;
        case AuthenticationProviderType.LiveId:
        case AuthenticationProviderType.Federation:
        case AuthenticationProviderType.OnlineFederation:
          _mpsConfig.AppSettings.Settings.Remove("UserName");
          _mpsConfig.AppSettings.Settings.Add("UserName", _serverConnect.config.Credentials.UserName.UserName);
          _mpsConfig.AppSettings.Settings.Remove("Domain");
          _mpsConfig.AppSettings.Settings.Add("Domain", "");
          break;
      }
      _mpsConfig.AppSettings.Settings.Remove("Password");
      _mpsConfig.AppSettings.Settings.Add("Password", tbPassword.Text);

      _mpsConfig.AppSettings.Settings.Remove("EndpointType");
      _mpsConfig.AppSettings.Settings.Add("EndpointType", _serverConnect.config.EndpointType.ToString());
      _mpsConfig.AppSettings.Settings.Remove("UserPrincipalName");
      _mpsConfig.AppSettings.Settings.Add("UserPrincipalName", _serverConnect.config.UserPrincipalName ?? String.Empty);

      try
      {
        _mpsConfig.Save();
        MessageBox.Show("Configuration successfully saved!", "Configuration saved!", MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
      catch (Exception)
      {
        MessageBox.Show("There was a problem saving the configuration!\nPlease make sure you are running the configuration tool as administrator!", "An error occured!", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
    }
  }
}
